package com.lxy.exportword.controller;

import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.data.PictureRenderData;
import com.deepoove.poi.plugin.table.LoopColumnTableRenderPolicy;
import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy;
import com.lxy.exportword.constant.WordConstant;
import com.lxy.exportword.entity.base.AbnormalSituationPoint;
import com.lxy.exportword.entity.base.AbnormalSituationPointReview;
import com.lxy.exportword.entity.base.RectificationStatisticsTable;
import com.lxy.exportword.entity.base.UavFlightRecordSheet;
import com.lxy.exportword.entity.cqzhixian.CQExceptionSummarize;
import com.lxy.exportword.entity.jiangdu.ExceptionSummarize;
import com.lxy.exportword.entity.moxi.*;
import com.lxy.exportword.entity.shunan.ShuNanAbnormalSituationPoint;
import com.lxy.exportword.entity.shunan.ShuNanGasTrunkLine;
import com.lxy.exportword.entity.shunan.ShuNanHeader;
import com.lxy.exportword.exception.BizException;
import com.lxy.exportword.service.ICQZhiXianService;
import com.lxy.exportword.service.IJiangDuService;
import com.lxy.exportword.service.IMoXiService;
import com.lxy.exportword.service.IShuNanService;
import com.lxy.exportword.util.WordUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.beans.IntrospectionException;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.IntStream;
/**
 * word导出接口层
 * @author LiuXiaoYu ZhangLiXiang
 */
@RestController
@RequestMapping("/word")
@Slf4j
public class WordController {

    @Value("${outFile.menu}")
    private String basePath;

    private final IMoXiService moXiService;
    private final IJiangDuService jiangDuService;
    private final ICQZhiXianService cqZhiXianService;
    private final IShuNanService shuNanService;

    @Autowired
    public WordController(IMoXiService moXiService, IJiangDuService jiangDuService, IShuNanService shuNanService, ICQZhiXianService cqZhiXianService) {
        this.moXiService = moXiService;
        this.shuNanService = shuNanService;
        this.jiangDuService = jiangDuService;
        this.cqZhiXianService = cqZhiXianService;
    }

    /**
     * 导出磨溪异常情况识别表
     * @param response
     */
    @GetMapping("/moxi")
    public void downloadWord(HttpServletResponse response){
        response.setContentType("application/vnd.ms-excel");
        response.setHeader("Content-Disposition", "attachment;filename=moxi.docx");
       /* word模板地址*/
        String resource=basePath+"磨溪异常情况识别记录表（07.21-07.27）.docx";

        Map<String, Object> map=new HashMap<>();

        /*-------------------------------------磨溪前两页------------------------*/
        MoXiHeader moXiHeader=moXiService.getAllMoXiHeader();
        Map<String, Object> moxiHeaderMap;
        try {
             moxiHeaderMap = WordUtil.getAllFieldNameAndValueToMap(moXiHeader);
        } catch (IntrospectionException e) {
            log.info("磨溪前两页反射异常:{},{}",e,e.getMessage());
            throw new BizException(e.getMessage());
        }

        /*-------------------------集输气干线------------------------------------*/
        List<GasGatheringTransmissionTrunkLine> gasGatheringTransmissionTrunkLineList=moXiService.getAllTableExceptions();
        //计算合计值
        BigDecimal gasTotal=WordUtil.getTotal(gasGatheringTransmissionTrunkLineList);
        map.put("gasTotal",gasTotal.toString());

        /*-------------------------转注水干线-----------------------------------*/
        List<TransferMainLineWaterInjection> transferMainLineWaterInjectionLinkedList=moXiService.getTransferMainLineWaterTableExceptions();
        //计算合计值
        BigDecimal transferWaterTotal=WordUtil.getTotal(transferMainLineWaterInjectionLinkedList);
        //放入map
        map.put("waterTotal",transferWaterTotal.toString());

        /*-------------------------异常情况点---------------------------------*/
        //通过列表循环创建模板表格
        List<AbnormalSituationPoint> abnormalSituationPointList=moXiService.getAllAbnormalSituationPointList();
        //创建区块对数据格式
        List<Map<String,Object>> blockPairList=new ArrayList<>();
        IntStream.range(0,abnormalSituationPointList.size()).forEach(i->{
            //TODO 反射收集改类及其父类所有属性,直接往map(key->属性名称,value->属性值)里塞东西
            Map<String,Object> abnormalSituationMap;
            try {
                abnormalSituationMap = WordUtil.getAllFieldNameAndValueToMap(abnormalSituationPointList.get(i));
                if (abnormalSituationMap.containsKey(WordConstant.TABLE_SUBTITLE)){
                    /*根据复查异常情况的个数动态修改标题 比如2.1.1/2.1.2/2.1.3*/
                    String tableSubtitle = (String) abnormalSituationMap.get(WordConstant.TABLE_SUBTITLE);
                    //动态更改标题
                    String afterPoint=String.valueOf(i+1);
                    tableSubtitle="2.1."+afterPoint+"、"+tableSubtitle;
                    abnormalSituationMap.put(WordConstant.TABLE_SUBTITLE,tableSubtitle);
                }

            } catch (IntrospectionException e) {
                log.info("异常情况点反射异常:{},{}",e,e.getMessage());
                throw new BizException(e.getMessage());
            }
            blockPairList.add(abnormalSituationMap);
        });

        /*-------------------------复查异常情况--------------------------------*/
        List<AbnormalSituationPointReview> abnormalSituationPointReviewList=moXiService.getAllAbnormalSituationPointReviewList();
        //创建区块对数据格式
        List<Map<String,Object>> blockPairCheckList=new ArrayList<>();
        for (int i = 0; i < abnormalSituationPointReviewList.size(); i++) {
            //TODO 反射收集改类及其父类所有属性,直接往map(key->属性名称,value->属性值)里塞东西
            Map<String,Object> abnormalSituationPointReviewMap;
            try {
                abnormalSituationPointReviewMap = WordUtil.getAllFieldNameAndValueToMap(abnormalSituationPointReviewList.get(i));
                if (abnormalSituationPointReviewMap.containsKey(WordConstant.TABLE_SUBTITLE)){
                    /*根据异常记录点的个数动态修改标题 比如2.2.1/2.2.2/2.2.3*/
                    String tableSubtitle = (String) abnormalSituationPointReviewMap.get(WordConstant.TABLE_SUBTITLE);
                    //动态更改标题
                    String afterPoint=String.valueOf(i+1);
                    tableSubtitle="2.2."+afterPoint+"、"+tableSubtitle;
                    abnormalSituationPointReviewMap.put(WordConstant.TABLE_SUBTITLE,tableSubtitle);
                }

            } catch (IntrospectionException e) {
                log.info("复查异常情况反射异常:{},{}",e,e.getMessage());
                throw new BizException(e.getMessage());
            }
            blockPairCheckList.add(abnormalSituationPointReviewMap);
        }

        /*-------------------------附件1：异常点整改情况统计表-----------------------------*/
        List<RectificationStatisticsTable> rectificationStatisticsTableList=moXiService.getAllRectificationStatistics();
        //附件名称
        map.put("rectificationAbnormalPointsTitle","附件1：异常点整改情况统计表");

        /*-------------------------附件2：无人机飞行记录表----------------------------------*/
        UavFlightRecordSheet uavFlightRecordSheet=moXiService.getAllUavFlightRecord();
            //TODO 反射收集改类及其父类所有属性,直接往map(key->属性名称,value->属性值)里塞东西
            Map<String,Object> uavFlightRecordSheetMap;
            try {
                uavFlightRecordSheetMap = WordUtil.getOnlySelfFieldNameAndValue(uavFlightRecordSheet);
            } catch (IntrospectionException e) {
                log.info("无人机飞行记录反射异常:{},{}",e,e.getMessage());
                throw new BizException(e.getMessage());
            }

        map.put("uavFlightRecordSheetTitle","附件2：无人机飞行记录表");

        /*-------------------------策略渲染----------------------------------*/
        // 读取模板templatePath并将paramMap的内容填充进模板，即编辑模板(compile)+渲染数据(render)
        LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
        Configure config = Configure.builder()
                //集输气干线
                .bind("Gas", policy)
                //转注水主线
                .bind("TransferWater",policy)
                //管线类型(异常情况点和复查异常情况中都有管线类型)
                .bind("pipelineType",policy)
                //复查异常情况中复查记录
                .bind("historicalReviewRecords",policy)
                //附件1 异常点整改情况统计表
                .bind("table",policy)
                .build();
         map.put("Gas", gasGatheringTransmissionTrunkLineList);
         map.put("TransferWater",transferMainLineWaterInjectionLinkedList);
         map.put("blockPairList",blockPairList);
         map.put("blockPairCheckList",blockPairCheckList);
         map.put("table",rectificationStatisticsTableList);

         //附件2 无人机飞行记录表
        Map<String, Object> combineResultMap=new HashMap<>();
        combineResultMap.putAll(map);
        combineResultMap.putAll(moxiHeaderMap);
        combineResultMap.putAll(uavFlightRecordSheetMap);
        XWPFTemplate template = XWPFTemplate.compile(resource, config).render(combineResultMap);

        //这里进行导出
        WordUtil.downloadWord(response,template);
    }

    /**
     * 导出蜀南异常情况识别表(07.12-07.18)
     * @param response
     */
    @GetMapping("/shunan")
    public void downloadShuNan(HttpServletResponse response){
        response.setContentType("application/vnd.ms-excel");
        response.setHeader("Content-Disposition", "attachment;filename=shunan.docx");
        /* word模板地址*/
        String resource=basePath+"蜀南异常情况识别记录表（07.12-07.18）.docx";

        Map<String, Object> map=new HashMap<>();
        /*------------------------蜀南模板前两页-----------------------------------*/
        ShuNanHeader shuNanHeader=shuNanService.getAllShuNanHeader();
        Map<String, Object> shuNanHeaderMap;
        try {
            shuNanHeaderMap = WordUtil.getAllFieldNameAndValueToMap(shuNanHeader);
        } catch (IntrospectionException e) {
            log.info("蜀南前两页反射异常:{},{}",e,e.getMessage());
            throw new BizException(e.getMessage());
        }

        /*------------------------集输气干线---------------------------------------*/
        List<ShuNanGasTrunkLine> shuNanGasTrunkLineList=shuNanService.getAllShuNanGasTrunkLineList();
        //计算合计
        //计算合计值
        BigDecimal gasTotal=WordUtil.getTotal(shuNanGasTrunkLineList);
        map.put("gasTotal",gasTotal.toString());

        //TODO 除每一行循环之外还要加入图片循环 相当于循环里套循环

        /*-------------------------异常情况点---------------------------------*/
        //通过列表循环创建模板表格
        List<ShuNanAbnormalSituationPoint> shuNanAbnormalSituationPointList=shuNanService.getAllShuNanAbnormalSituationPointList();
        //创建区块对数据格式
        List<Map<String,Object>> blockPairList=new ArrayList<>();
        IntStream.range(0,shuNanAbnormalSituationPointList.size()).forEach(i->{
            //TODO 反射收集改类及其父类所有属性,直接往map(key->属性名称,value->属性值)里塞东西
            Map<String,Object> abnormalSituationMap;
            try {
                abnormalSituationMap = WordUtil.getAllFieldNameAndValueToMap(shuNanAbnormalSituationPointList.get(i));
                if (abnormalSituationMap.containsKey(WordConstant.TABLE_SUBTITLE)){
                    /*根据复查异常情况的个数动态修改标题 比如2.1.1/2.1.2/2.1.3*/
                    String tableSubtitle = (String) abnormalSituationMap.get(WordConstant.TABLE_SUBTITLE);
                    //动态更改标题
                    String afterPoint=String.valueOf(i+1);
                    tableSubtitle="2.1."+afterPoint+"、"+tableSubtitle;
                    abnormalSituationMap.put(WordConstant.TABLE_SUBTITLE,tableSubtitle);
                }

            } catch (IntrospectionException e) {
                log.info("异常情况点反射异常:{},{}",e,e.getMessage());
                throw new BizException(e.getMessage());
            }
            blockPairList.add(abnormalSituationMap);
        });

        /*-------------------------附件1：异常点整改情况统计表-----------------------------*/
        List<RectificationStatisticsTable> rectificationStatisticsTableList=moXiService.getAllRectificationStatistics();
        //附件名称
        map.put("rectificationAbnormalPointsTitle","附件1：异常点整改情况统计表");

        /*-------------------------附件2：无人机飞行记录表----------------------------------*/
        UavFlightRecordSheet uavFlightRecordSheet=moXiService.getAllUavFlightRecord();
        //TODO 反射收集改类及其父类所有属性,直接往map(key->属性名称,value->属性值)里塞东西
        Map<String,Object> uavFlightRecordSheetMap;
        try {
            uavFlightRecordSheetMap = WordUtil.getOnlySelfFieldNameAndValue(uavFlightRecordSheet);
        } catch (IntrospectionException e) {
            log.info("无人机飞行记录反射异常:{},{}",e,e.getMessage());
            throw new BizException(e.getMessage());
        }

        map.put("uavFlightRecordSheetTitle","附件2：无人机飞行记录表");

        /*-------------------策略渲染---------------------*/

        LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
        Configure config = Configure.builder()
                //集输气干线
                .bind("Gas", policy)
                //管线类型(异常情况点和复查异常情况中都有管线类型)
                .bind("pipelineType",policy)
                //附件1 异常点整改情况统计表
                .bind("table",policy)
                .build();
        map.put("Gas", shuNanGasTrunkLineList);
        map.put("blockPairList",blockPairList);
        map.put("table",rectificationStatisticsTableList);

        //附件2 无人机飞行记录表
        Map<String, Object> combineResultMap=new HashMap<>();
        combineResultMap.putAll(map);
        combineResultMap.putAll(shuNanHeaderMap);
        combineResultMap.putAll(uavFlightRecordSheetMap);
        XWPFTemplate template = XWPFTemplate.compile(resource, config).render(combineResultMap);

        //这里进行导出
        WordUtil.downloadWord(response,template);
    }

    /**
     * 导出重庆支线
     * @param response
     */
    @GetMapping("/CQzhixian")
    public void CQzhixian(HttpServletResponse response){
        response.setContentType("application/vnd.ms-excel");
        response.setHeader("Content-Disposition", "attachment;filename=CQzhixian.docx");
        String resource=basePath+"重庆支线异常情况识别记录表-江北运销部（2021年7月）.docx";
        //临时数据
        HashMap<String, Object> hashMap = new HashMap<>();
        //普通数据
        Map<String, Object> map=cqZhiXianService.getMap();
        //异常点表格数据
        List<CQExceptionSummarize> list=cqZhiXianService.getAllTableExceptions();
        BigDecimal gasTotal=WordUtil.getTotal(list);
        map.put("gasTotal",gasTotal.toString());

        // 读取模板templatePath并将paramMap的内容填充进模板，即编辑模板(compile)+渲染数据(render)
        LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
        hashMap.put("Gas", list);
        /*-------------------------异常情况点---------------------------------*/
        //通过列表循环创建模板表格
        List<ShuNanAbnormalSituationPoint> cqAbnormalSituationPointList=cqZhiXianService.getAllShuNanAbnormalSituationPointList();
        //创建区块对数据格式
        List<Map<String,Object>> blockPairList=new ArrayList<>();
        IntStream.range(0,cqAbnormalSituationPointList.size()).forEach(i->{
            //TODO 反射收集改类及其父类所有属性,直接往map(key->属性名称,value->属性值)里塞东西
            Map<String,Object> abnormalSituationMap;
            try {
                abnormalSituationMap = WordUtil.getAllFieldNameAndValueToMap(cqAbnormalSituationPointList.get(i));
                if (abnormalSituationMap.containsKey(WordConstant.TABLE_SUBTITLE)){
                    /*根据复查异常情况的个数动态修改标题 比如2.1.1/2.1.2/2.1.3*/
                    String tableSubtitle = (String) abnormalSituationMap.get(WordConstant.TABLE_SUBTITLE);
                    //动态更改标题
                    String afterPoint=String.valueOf(i+1);
                    tableSubtitle="2.1."+afterPoint+"、"+tableSubtitle;
                    abnormalSituationMap.put(WordConstant.TABLE_SUBTITLE,tableSubtitle);
                }

            } catch (IntrospectionException e) {
                log.info("异常情况点反射异常:{},{}",e,e.getMessage());
                throw new BizException(e.getMessage());
            }
            blockPairList.add(abnormalSituationMap);
        });
        hashMap.put("blockPairList",blockPairList);
        /*-------------------------异常整改---------------------------------*/
        LoopColumnTableRenderPolicy policy2 = new LoopColumnTableRenderPolicy();
        List<RectificationStatisticsTable> allRectificationStatistics = cqZhiXianService.getAllRectificationStatistics();
        hashMap.put("table", allRectificationStatistics);
        /*-------------------------无人机飞行记录表---------------------------------*/
        UavFlightRecordSheet uavFlightRecordSheet=cqZhiXianService.getAllUavFlightRecord();
        //TODO 反射收集改类及其父类所有属性,直接往map(key->属性名称,value->属性值)里塞东西 避免代码冗余
        Map<String,Object> uavFlightRecordSheetMap;
        try {
            uavFlightRecordSheetMap = WordUtil.getOnlySelfFieldNameAndValue(uavFlightRecordSheet);
        } catch (IntrospectionException e) {
            log.info("无人机飞行记录反射异常:{},{}",e,e.getMessage());
            throw new BizException(e.getMessage());
        }
        map.put("uavFlightRecordSheetTitle","附件2：无人机飞行记录表");
        Configure config = Configure.builder()
                .bind("Gas", policy)
                .bind("table", policy2)
                .bind("pipelineType",policy).build();


        map.putAll(hashMap);
        map.putAll(uavFlightRecordSheetMap);

        XWPFTemplate template = XWPFTemplate.compile(resource, config).render(map);
        WordUtil.downloadWord(response,template);
    }

    /**
     * 导出讲渡
     * @param response
     */
    @GetMapping("/jiangdu")
    public void jiangDu(HttpServletResponse response){
        response.setContentType("application/vnd.ms-excel");
        response.setHeader("Content-Disposition", "attachment;filename=CQjiangdu.docx");
        String resource=basePath+"重庆讲渡线B段异常情况识别记录表（第二十八次巡检）.docx";
        //普通数据
        Map<String, Object> map=jiangDuService.getMap();


        //异常点表格数据
        List<ExceptionSummarize> list=jiangDuService.getAllTableExceptions();
        BigDecimal gasTotal=WordUtil.getTotal(list);
        map.put("waterTotal",gasTotal.toString());

        // 读取模板templatePath并将paramMap的内容填充进模板，即编辑模板(compile)+渲染数据(render)
        LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
        Configure gasConfig = Configure.builder()
                .bind("Gas", policy).build();
        map.put("Gas", list);
        XWPFTemplate template = XWPFTemplate.compile(resource, gasConfig).render(map);
        //这里进行导出
        WordUtil.downloadWord(response,template);
    }
}
